#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# account_forms.py
#
#  Copyright (c) 2007 INdT (Instituto Nokia de Technologia)
#                2007 Kenneth Christiansen
#
#  Authors: Kenneth Rohde Christiansen <kenneth.christiansen@gmail.com>
#           Marcelo Lira dos Santos <setanta@gmail.com>
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
#  USA

import pygtk
pygtk.require("2.0")
import gtk
import gobject

import icon_theme
import util
from profiles import Profiles

class AccountFormFactory:

    def __init__(self):
        self.profiles = Profiles()


    def build_account_form(self, profile_id='google-talk'):
        if profile_id not in self.profiles.get_profile_ids():
            return None

        params = self.profiles.get_profile_parameters(profile_id)

        rows = len(params)
        if rows < 1:
            return None

        account_form = AbstractAccountForm(rows, 2, profile_id)

        names = params.keys()
        i = names.index('account')
        names.insert(0, names.pop(i))
        i = names.index('password')
        names.insert(1, names.pop(i))

        reorder = []
        i = 0
        for name in names:
            type = params[name][0]
            if type == 'boolean':
                reorder.append(name)
            else:
                reorder.insert(i, name)
                i += 1

        names = reorder

        for name in names:
            widget, label = self.build_field(name.title(), params[name])
            value = params[name][1]
            if value:
                fixed = value.find('fixed') > -1
            else:
                fixed = False
            account_form.add_field_row(name, widget, label, fixed)

        return account_form


    def build_field(self, field_name, attributes):
        type, value, hidden = attributes

        if value == None:
            value = ''

        pos = value.find('fixed')
        fixed = (pos > -1)
        if fixed:
            value = value[:pos].strip()

        if type == 'string':
            pair = self.build_string_field(field_name, value, fixed)
        elif type == 'boolean':
            value = 'true' in value
            pair = self.build_boolean_field(field_name, value, fixed)
        elif type == 'uint':
            value = int (value)
            pair = self.build_uint_field(field_name, value, fixed)

        return pair


    def build_string_field(self, field_name, default_value='', fixed=False):
        label = gtk.Label('%s:' % field_name)
        label.set_alignment(0, 0.5)
        entry = gtk.Entry()
        entry.set_editable(not fixed)
        if default_value:
            entry.set_text(default_value)

        if field_name.lower() == 'password':
            entry.set_visibility(False)

        return (entry, label)


    def build_uint_field(self, field_name, default_value=0, fixed=False):
        label = gtk.Label('%s:' % field_name)
        label.set_alignment(0, 0.5)
        spin_adj = gtk.Adjustment(default_value, 0, 65535, 1, 10, 10)
        spin = gtk.SpinButton(adjustment=spin_adj)
        spin.set_numeric(True)
        #spin.set_editable(not fixed)

        return (spin, label)


    def build_boolean_field(self, field_name, default_value=False, fixed=False):
        check = gtk.CheckButton(field_name)
        #check.set_editable(not fixed)
        check.set_active(default_value)

        return (check, None)


class AbstractAccountForm(gtk.Table):

    __gsignals__ = {
        'value-changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT, )),
    }


    def __init__(self, rows, columns, profile_id):
        gtk.Table.__init__(self, rows, columns)

        self.profile_id = profile_id

        self.set_row_spacings(6)
        self.set_col_spacings(9)

        self.field = {}
        self.field_default = {}
        self.row = 0


    def add_field_row(self, field_name, data_widget=None, label_widget=None, fixed=False):
        self.field[field_name] = data_widget
        self.field_default[field_name] = self.get_value(field_name)

        if fixed:
            return

        if type(data_widget) == gtk.CheckButton:
            data_widget.connect('toggled', self.on_value_changed, field_name)
        else:
            data_widget.connect('changed', self.on_value_changed, field_name)

        if label_widget != None:
            self.attach(label_widget, 0, 1, self.row, self.row + 1,
                    gtk.FILL, gtk.FILL)
            self.attach(data_widget, 1, 2, self.row, self.row + 1,
                    gtk.EXPAND|gtk.FILL, gtk.FILL)
        else:
            self.attach(data_widget, 0, 2, self.row, self.row + 1,
                    gtk.EXPAND|gtk.FILL, gtk.FILL)
        self.row += 1


    def get_value(self, field_name):
        widget = self.field[field_name]

        if widget == None:
            return self.field_default[field_name]

        if type(widget) == gtk.Entry:
            return widget.get_text()
        elif type(widget) == gtk.SpinButton:
            return widget.get_value_as_int()
        elif type(widget) == gtk.CheckButton:
            return widget.get_active()


    def get_data(self):
        data = {}

        for field_name in self.field.keys():
            data[field_name] = self.get_value(field_name)

        return data


    def set_value(self, field_name, value):
        widget = self.field[field_name]

        if type(widget) == gtk.Entry:
            widget.set_text(value)
        elif type(widget) == gtk.SpinButton:
            widget.set_value(value)
        elif type(widget) == gtk.CheckButton:
            widget.set_active(value)


    def set_data(self, data):
        for field_name in data.keys():
            self.set_value(field_name, data[field_name])


    def reset_data(self):
        self.set_data(self.field_default)


    def on_value_changed(self, widget, field_name):
        self.emit('value-changed', field_name)


'''
class AbstractAccountForm(gtk.VBox):

    __gsignals__ = {
        'account-id-changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT, )),
    }

    def __init__(self):
        gtk.VBox.__init__(self, False, 0)

        self.settings_vbox_alignment = gtk.Alignment(0.5, 0.5, 1, 1)
        self.pack_start(self.settings_vbox_alignment, False, False, 3)
        self.settings_vbox_alignment.set_padding(0, 0, 15, 6)

        self.settings_vbox = gtk.VBox(False, 6)
        self.settings_vbox_alignment.add(self.settings_vbox)

        self.table = gtk.Table(6, 2, False)
        self.settings_vbox.pack_start(self.table, True, True, 0)
        self.table.set_row_spacings(6)
        self.table.set_col_spacings(9)

        self.account_id_label = gtk.Label("Account-ID:")
        self.table.attach(self.account_id_label, 0, 1, 1, 2, \
                xoptions=gtk.FILL, xpadding=0, ypadding=0)
        self.account_id_label.set_alignment(0, 0.5)

        self.password_label = gtk.Label("Password:")
        self.table.attach(self.password_label, 0, 1, 2, 3, \
                xoptions=gtk.FILL, xpadding=0, ypadding=0)
        self.password_label.set_alignment(0, 0.5)

        self.account_id_entry = gtk.Entry()
        self.account_id_entry.connect('changed', self.on_account_id_entry_changed)
        self.table.attach(self.account_id_entry, 1, 2, 1, 2, \
                xoptions=gtk.EXPAND|gtk.FILL, xpadding=0, ypadding=0)

        self.password_entry = gtk.Entry()
        self.password_entry.set_visibility(False)
        self.table.attach(self.password_entry, 1, 2, 2, 3, \
                xoptions=gtk.EXPAND|gtk.FILL, xpadding=0, ypadding=0)


    def reset_form(self):
        self.set_account_id('')
        self.set_password('')


    def set_account(self, account):
        self.set_account_id(account.account_id)
        self.set_password(account.password)


    def set_account_id_label(self, label):
        self.account_id_label.set_text(label)


    def set_password_label(self, label):
        self.password_label.set_text(label)


    def set_account_id(self, account_id):
        self.account_id_entry.set_text(account_id)


    def set_password(self, password):
        self.password_entry.set_text(password)


    def get_account(self, account):
        account = account.Account()
        account.account_id = self.get_account_id()
        account.password = self.get_password()

        return account


    def get_account_id(self):
        return self.account_id_entry.get_text()


    def get_password(self):
        return self.password_entry.get_text()


    def on_account_id_entry_changed(self, entry):
        self.emit('account-id-changed', entry.get_text())


class JabberAccountForm(AbstractAccountForm):

    def __init__(self):
        AbstractAccountForm.__init__(self)
        self.resource_label = gtk.Label("Resource:")
        self.table.attach(self.resource_label, 0, 1, 3, 4, \
                xoptions=gtk.FILL, xpadding=0, ypadding=0)
        self.resource_label.set_alignment(0, 0.5)

        self.server_label = gtk.Label("Server:")
        self.table.attach(self.server_label, 0, 1, 4, 5, \
                xoptions=gtk.FILL, xpadding=0, ypadding=0)
        self.server_label.set_alignment(0, 0.5)

        self.resource_entry = gtk.Entry()
        self.table.attach(self.resource_entry, 1, 2, 3, 4, \
                xoptions=gtk.EXPAND|gtk.FILL, xpadding=0, ypadding=0)

        self.server_entry = gtk.Entry()
        self.table.attach(self.server_entry, 1, 2, 4, 5, \
                xoptions=gtk.EXPAND|gtk.FILL, xpadding=0, ypadding=0)

        self.port_label = gtk.Label("Port:")
        self.table.attach(self.port_label, 0, 1, 5, 6, \
                xoptions=gtk.FILL, xpadding=0, ypadding=0)
        self.port_label.set_alignment(0, 0.5)

        self.spinbutton_adj = gtk.Adjustment(5223, 0, 65535, 1, 10, 10)
        self.port_spinbutton = gtk.SpinButton(adjustment=self.spinbutton_adj)
        self.table.attach(self.port_spinbutton, 1, 2, 5, 6, \
                xoptions=gtk.EXPAND|gtk.FILL, xpadding=0, ypadding=0)

        self.use_encryption_checkbutton = gtk.CheckButton("Use encryption (SSL)")
        self.settings_vbox.pack_start(self.use_encryption_checkbutton, \
                False, False, 0)

        self.set_resource('Ereseva')


    def reset_form(self):
        AbstractAccountForm.reset_form(self)
        self.set_resource('Ereseva')
        self.set_server('talk.google.com')
        self.set_port(5223)
        self.set_use_encryption(False)


    def set_account(self, account):
        self.set_account_id(account.account_id)
        self.set_password(account.password)
        self.set_resource(account.resource)
        self.set_server(account.server)
        self.set_port(account.port)
        self.set_use_encryption(account.use_encryption)


    def set_account_id(self, account_id):
        self.account_id_entry.set_text(account_id)
        server = account_id.split('@')[-1]

        if server == 'gmail.com':
            self.set_server('talk.google.com')
        else:
            self.set_server(server)


    def set_resource(self, resource):
        self.resource_entry.set_text(resource)


    def set_server(self, server):
        self.server_entry.set_text(server)


    def set_port(self, port):
        self.port_spinbutton.set_value(port)


    def set_use_encryption(self, use=True):
        self.use_encryption_checkbutton.set_active(use)


    def get_account(self, account):
        account = account.JabberAccount()
        account.account_id = self.get_account_id()
        account.password = self.get_password()
        account.resource = self.get_resource()
        account.server = self.get_server()
        account.port = self.get_port()
        account.use_encryption = self.get_use_encryption()

        return account


    def get_resource(self):
        return self.resource_entry.get_text()


    def get_server(self):
        return self.server_entry.get_text()


    def get_port(self):
        return self.port_spinbutton.get_value()


    def get_use_encryption(self):
        return self.use_encryption_checkbutton.get_active()


class MsnAccountForm(AbstractAccountForm):

    def __init__(self):
        AbstractAccountForm.__init__(self)
'''

if __name__ == '__main__':
    window = gtk.Window()
    window.connect('destroy', gtk.main_quit)
    vbox = gtk.VBox()
    window.add(vbox)

    aff = AccountFormFactory()

    protocols = ['google-talk', 'jabber', 'msn-messenger', 'link-local']

    for protocol in protocols:
        table = aff.build_account_form(protocol)
        if table:
            vbox.pack_start(table)
            vbox.pack_start(gtk.HSeparator())

    window.show_all()
    gtk.main()

